package com.ctvit.framework.dao;

import java.util.List;
import java.util.Map;

import org.springframework.orm.ibatis.SqlMapClientCallback;

import com.ctvit.framework.domain.BaseBean;

/**
 * 基础DAO接口.
 *
 * 该DAO已经实现了所有可能的DAO操作，非必要情况，不需要创建新的DAO类.
 * @author Q-Wang
 */
public interface GenericDao {

	/**
	 * 执行sql,返回查询结果(List),这个查询不需要在ibatis的sqlmap里面作sql的配置,直接
	 * 执行一个sql语句.返回结果的每一条记录不映射到javabean,而是映射到一个Map.
	 * 
	 * @param sql
	 *            需要执行的sql
	 * @return 查询结果,其中List中的每个元素是一个Map,代表sql语句的一条结果,map中的每个key-value代表一个字段名-字段值
	 */
	public abstract List<Map<String,?>> executeSql(String sql);
	public abstract List executeSqlRowHandler(String sql);

	/**
	 * 执行sql,返回查询结果(List).
	 * 
	 * @param sqlid
	 *            需要执行的sql的id,这个id包括namespace,在sqlmap文件中配置
	 * @param parameter
	 *            sqlmap中指定的sql接受的参数,根据配置可能是String,javabean,或者map
	 * @return 查询结果,其中List中的每个元素是根据sqlmap中配置的returnclass来指定.
	 */
	public abstract <T> List<T> queryBySqlID(String sqlid, Object parameter);
	public abstract <T> List<T> queryBySqlIDPage(String sqlid, Object parameter,int pageNo, int pageSize);
	public abstract long queryBySqlIDPageCount(String sqlid, Object parameter);
	/**
	 * 执行update类型的sql,返回修改的行数.
	 * 
	 * @param sqlid
	 *            需要执行的sql的id,这个id包括namespace,在sqlmap文件中配置
	 * @param parameter
	 *            sqlmap中指定的sql接受的参数,根据配置可能是String,javabean,或者map
	 * @return 影响的行数
	 */
	public abstract int updateBySqlID(String sqlid,Object parameter);

	/**
	 * 执行修改类型的sql,返回修改的行数.
	 * 
	 * @param sqlid
	 *            需要执行的sql的id,这个id包括namespace,在sqlmap文件中配置
	 * @param parameter
	 *            sqlmap中指定的sql接受的参数,根据配置可能是String,javabean,或者map
	 * @return 影响的行数
	 */
	public abstract int deleteBySqlID(String sqlid,Object parameter);

	/**
	 * 执行insert类型的sql,返回修改的行数.
	 * 
	 * @param sqlid
	 *            需要执行的sql的id,这个id包括namespace,在sqlmap文件中配置
	 * @param parameter
	 *            sqlmap中指定的sql接受的参数,根据配置可能是String,javabean,或者map
	 * @return
	 */
	public abstract Object insertBySqlID(String sqlid,Object parameter);

	/**
	 * 数据库插入操作.
	 * 
	 * @param value 要插入的对象
	 * @return 对象的主键.
	 */
	public abstract <T extends BaseBean> Long insert(T value);

	/**
	 * 通过主键更新域对象.
	 * 
	 * @param value
	 *            域对象
	 * @param filter
	 *            域对象的属性数组，仅更新这些属性值
	 * @return 更新记录数
	 */
	public abstract <T extends BaseBean> int update(T value, String[] filter);

	/**
	 * 通过主键更新域对象.
	 * 
	 * @param value
	 *            域对象
	 * @param filter
	 *            域对象的属性数组，不更新这些属性值
	 * @return 更新记录数
	 */
	public abstract <T extends BaseBean> int updateExclusive(T value, String[] filter);

	/**
	 * 按指定条件更新相应记录，仅更新filter中指定的域对象中的值.
	 * 
	 * @param value
	 *            包含更新值的域对象
	 * @param filter
	 *            更新的属性数组，为空更新所有属性
	 * @param condition
	 *            筛选条件
	 * @return 更新记录数
	 */
	public abstract <T extends BaseBean> int updateByCondition(T value, String[] filter,
			Condition condition);
	public abstract <T extends BaseBean> int updateExclusiveByCondition(T value, String[] filter,
			Condition condition);

	/**
	 * 删除指定id的记录.
	 * 
	 * @param clazz
	 *            域对象类名
	 * @param id
	 *            主键值
	 * @return 删除记录数
	 */
	public abstract int removeById(Class<? extends BaseBean> clazz, Long id);

	/**
	 * 按指定条件删除相应记录.
	 * 
	 * @param clazz
	 *            域对象类名
	 * @param condition
	 *            筛选条件
	 * @return 删除记录数
	 */
	public abstract int removeByCondition(Class<? extends BaseBean> clazz, Condition condition);

	/**
	 * 取得指定主键值的记录
	 * 
	 * @param clazz
	 *            域对象类名
	 * @param id
	 *            主键值
	 * @return 域对象
	 */
	public abstract <T extends BaseBean> T getById(Class<T> clazz, Long id);

	/**
	 * 按指定条件查询，并通过排序条件进行排序
	 * 
	 * @param clazz
	 *            域对象类名
	 * @param condition
	 *            筛选条件
	 * @param orders
	 *            排序条件
	 * @return 域对象列表
	 */
	public abstract <T extends BaseBean> List<T> getByCondition(Class<T> clazz, Condition condition,
			OrderPart orders);

	/**
	 * 按指定条件查询
	 * 
	 * @param clazz
	 *            域对象类名
	 * @param condition
	 *            筛选条件
	 * @return 域对象
	 */
	public abstract <T extends BaseBean> T getObjectByCondition(Class<T> clazz, Condition condition);

	/**
	 * 按指定条件进行分页查询，并通过排序条件进行排序
	 * 
	 * @param clazz
	 *            域对象类名
	 * @param condition
	 *            筛选条件
	 * @param orders
	 *            排序条件
	 * @param pageNo
	 *            页号,起始页号为0
	 * @param pageSize
	 *            每页显示记录数
	 * @return 域对象列表
	 */
	public abstract <T extends BaseBean> List<T> getPagedByCondition(Class<T> clazz, Condition condition,
			OrderPart orders, int pageNo, int pageSize);

	/**
	 * 按指定条件统计记录数
	 * 
	 * @param clazz
	 *            域对象类名
	 * @param condition
	 *            筛选条件
	 * @return 记录数
	 */
	public abstract long getCountByCondition(Class<? extends BaseBean> clazz, Condition condition);

	/**
	 * 批量Insert操作
	 * 
	 * @param objects Object List to Insert. Type:List&lt;BaseBean&gt;
	 * @return SQL语句影响行数(本次操作插入记录数)
	 */
	public abstract int batchInsert(final List<? extends BaseBean> objects);
	public abstract int batchUpdate(final Class<? extends BaseBean>  clazz, final List<? extends BaseBean> objects, final String[] filter);

	/**
	 * 批量Insert操作
	 * 
	 * @param objects Object List to Insert. Type:List&lt;BaseBean&gt;
	 * @return SQL语句影响行数(本次操作插入记录数)
	 */
	public int batchInsert(final Class<? extends BaseBean> clazz, final List<Map<String,Object>> objects);

	/**
	 * Insert操作.
	 * 
	 * @param clazz 对象类型.
	 * @param value property,value键值对
	 * @return id
	 */
	public Long insert(Class<? extends BaseBean> clazz, Map<String, Object> value);

	/**
	 * 通过主键更新域对象.
	 * 
	 * @param value
	 *            域对象
	 * @param filter
	 *            域对象的属性数组，仅更新这些属性值
	 * @return 更新记录数
	 */
	public int update(Class<? extends BaseBean> clazz, Map<String,?> value, String[] filter);

	/**
	 * 通过主键更新域对象.
	 * 
	 * @param value
	 *            域对象
	 * @param filter
	 *            域对象的属性数组，不更新这些属性值
	 * @return 更新记录数
	 */
	public int updateExclusive(Class<? extends BaseBean> clazz, Map<String,?> value, String[] filter);

	/**
	 * Ibatis native 回调.
	 * 
	 * @param callback Ibatis native 回调
	 * @return
	 */
	public <T> T execute(SqlMapClientCallback<T> callback);
	public abstract int updateBySqlStr(String sql);
	public abstract int deleteBySqlStr(String sql);
	//	/**
	//	 * update操作
	//	 *
	//	 * @param objects Object List to Insert. Type:List&lt;Map&gt;
	//	 * @return SQL语句影响行数(本次操作插入记录数)
	//	 */
	//	public int updateBySqlID(String sqlID,Map data);
	//	/**
	//	 * insert操作
	//	 *
	//	 * @param objects Object List to Insert. Type:List&lt;Map&gt;
	//	 * @return SQL语句影响行数(本次操作插入记录数)
	//	 */
	//	public Long insertBySqlID(String sqlID,Map data);

	public Long nextId();
}